// 1. 可计算的属性名
// 类的方法名不确定, 可以使用es6中的可计算属性名
; (function () {
  return
  const setName = 'getName'
  class Animal {
    constructor(name) {
      this.name = name
    }
    [setName](name) {
      return this.name = name
    }
  }
  let a = new Animal("小狗")
  console.log(a[setName]('小猫'));
})();

// 2. getter和setter
// 原来的getter和setter,   通过Object.defineProperty设置的
// 使用get  和 set 赋值的属性不在原型上面.
; (function () {
  return
  class Animal {
    constructor(type, name, age, sex, age2) {
      this.type = type;
      this.name = name;
      // this._age = age;
      this.setAge(age)
      this.sex = sex;
      this.age3 = age2
    }
    // 创建一个age2属性,并给它加上一个getter,
    // 读取该属性时,会运行该函数
    get age3() {
      return this.age2 + '岁'
    }
    // 创建一个age属性, 并给它加上setter,
    // 给该属性赋值是,会运行该函数
    set age3(age2) {
      console.log('给age2进行复制');
      if (typeof age2 !== "number") {
        throw new TypeError("age property must be a number!")
      }
      if (age2 < 0) {
        age2 = 0
      }
      else if (age2 > 1000) {
        age2 = 1000
      }
      this.age2 = age2
    }
    // 得到年龄
    getAge() {
      return this._age + '岁'
    }
    // 使用函数控制
    setAge(age) {
      if (typeof age !== "number") {
        throw new TypeError("age property must be a number!")
      }
      if (age < 0) {
        age = 0
      }
      else if (age > 1000) {
        age = 1000
      }
      this._age = age
    }
  }

  const a = new Animal("狗", "旺财", -100, "男", 55);
  //Animal { type: '狗', name: '旺财', _age: 0, sex: '男' }
  // console.log(a.getAge());
  // a.setAge('aa')

  a.age3 = 77
  console.log(a.age3, a.age2);
  console.log(a);
  // 上面的操作  _age感觉不像是一个属性. 
  // 其中 age3就是为了age2服务
})();

// 3.静态成员
; (function () {
  return
  class Animal {
    constructor(type, name, age, sex, age2) {
      this.type = type;
      this.name = name;
      // this._age = age;
      // this.setAge(age)
      this.sex = sex;
      this.age3 = age2
    }
    // 这种写法也是静态成员
    static abc2 = 1234
  }
  // 这个就是静态成员
  // 不过这中方法是分开的
  Animal.abc = 123
  console.log('直接访问静态成员', Animal.abc);
  console.log('直接访问静态成员', Animal.abc2);
  console.log(new Animal("狗", "旺财", -100, "男", 55))
})();

// 4. 字段初始化器
// 使用static的字段初始化器, 添加的是静态成员
// 没有使用static的字段初始化器,添加的成员位于对象上
// *** 箭头函数在字段初始化器位置上, 指向当前的对象
; (function () {
  return
  class Test {
    // 这里相当于下面的写法
    a = 1
    b = 2
    c = 3

    constructor() {
      // this.a = 1
      // this.b = 2
      // this.c = 3

      // 想当于
      this.print = () => {
        console.log(this.a)
      }
    }
    // 这样是绑定了对象的this,不在改变, 
    print = () => {
      console.log(this.a)
    }
  }
  const a = new Test()
  console.log(a)
  let obj = { a: 6 }
  let print = a.print.bind(obj) // 因为箭头函数没有this, 所以改变不了this指向
  print()
})();

// 5. 类表达式
; (function () {
  return
  const A = class { // 匿名类, 类表达式 因为类的本质是函数
    a = 1
    b = 2
  }
  const a = new A()
  console.log(a.a, a.b);
})();

// 6.装饰器 (只是了解一下即可,不记录)

